#include "cabac_encode.h"
#include "predict.h"
#include "encoder_logger.h"

/**
 * macroblock_layer语法，mb_type
 */
static inline void cabac_mb_type_intra( h264_ctx_t *context, h264_cabac_t *cb, int i_mb_type,
                                        int ctx0, int ctx1, int ctx2, int ctx3, int ctx4, int ctx5 )
{
    // TODO:add I4x4编码
    
    // 直接进行 I16x16编码
    // 通过表9-27确定mb_type的二进制码串
    intra16x16_pred_e i_pred = h264_get_actual_pred16x16((intra16x16_pred_e)context->cur_mb.i_intra16x16_pred_mode);
    // h264_cabac_encode_decision(cb, ctx0, 1);
    // x264_cabac_encode_terminal(cb);
    // h264_cabac_encode_decision( cb, ctx0, 1 );
    // x264_cabac_encode_terminal( cb );

    // h264_cabac_encode_decision(cb, ctx1, !!context->cur_mb.i_cbp_luma);
    // if (context->cur_mb.i_cbp_luma == 0)
    //     h264_cabac_encode_decision(cb, ctx2, 0);
    // else
    // {
    //     h264_cabac_encode_decision(cb, ctx2, 1);
    //     h264_cabac_encode_decision(cb, ctx3, h->mb.i_cbp_chroma >> 1);
    // }
    // h264_cabac_encode_decision(cb, ctx4, i_pred >> 1);
    // h264_cabac_encode_decision(cb, ctx5, i_pred & 1);

    INFO_LOG("HHHH\n");
}

static void cabac_mb_header_i(h264_ctx_t *ctx, h264_cabac_t *cb, mb_class_e mb_type, int chroma)
{
    int cb_ctx = 0;
    int neighbor = ctx->cur_mb.neighbors.i_neighbour;
    // 编码mb_type需要确定ctxIdxInc和ctxIdxOffset，ctxIdxOffset通过表9-25确定，ctxIdxInc在章节9.3.3.1.1.3
    // 下面代码是9.3.3.1.1.3的实现逻辑
    if (((neighbor & MB_LEFT) != 0) && (ctx->cur_mb.neighbors.i_mb_type_left != I_4x4)) {
        cb_ctx++;
    }

    if(((neighbor & MB_TOP != 0)) && (ctx->cur_mb.neighbors.i_mb_type_top != I_4x4)) {
        cb_ctx++;
    }
    // 编码mb_type 3为ctxIdxOffset cb_ctx为ctxIdxInc
    cabac_mb_type_intra(ctx, cb, mb_type, 3 + cb_ctx, 3 + 3, 3 + 4, 3 + 5, 3 + 6, 3 + 7);
}

void cabac_encode(h264_ctx_t *ctx, h264_cabac_t *cb)
{
    const int i_mb_pos_start = h264_cabac_pos(cb);
    cabac_mb_header_i(ctx, cb, ctx->cur_mb.type, 1);
    // 目前只编码I slice

}